package com.sh.data.engine.domain.feign.Service;

import com.alibaba.fastjson.JSON;
import com.sh.data.engine.domain.Isfd.domain.IsfdModelUploadDomain;
import com.sh.data.engine.domain.config.IsfdRequestConfig;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.util.Timeout;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Service
public class IsfdModelFileUploadService {

    @Value("${map.isfd.upload.url}")
    private String uploadUrl;

    @Autowired
    private IsfdTokenService isfdTokenService;

    @Autowired
    private IsfdRequestConfig isfdRequestConfig;

    private static final Logger logger = LoggerFactory.getLogger(IsfdModelFileUploadService.class);

    public IsfdModelUploadDomain uploadModelFile(File file, Map<String, String> formParams) {
        // 1. Socket 配置（缓冲区 + 超时）
        SocketConfig socketConfig = SocketConfig.custom()
                .setSndBufSize(65536)  // 发送缓冲区 64KB（影响上传）
                .setRcvBufSize(65536)  // 接收缓冲区 64KB（影响下载）
                .setSoTimeout(Timeout.ofSeconds(30))  // Socket 超时
                .build();

        // 2. 连接池配置
        PoolingHttpClientConnectionManager connectionManager =
                new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100);  // 最大连接数
        connectionManager.setDefaultMaxPerRoute(20);  // 每路由最大连接数
        connectionManager.setDefaultSocketConfig(socketConfig); // 设置 Socket 配置（缓冲区 + 超时）

        // 3. 请求超时配置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofSeconds(30))  // 连接超时
                .setConnectionRequestTimeout(Timeout.ofSeconds(30))  // 请求超时
                .build();

        // 4. 构建 HttpClient
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        try (httpClient) {
            HttpPost httpPost = new HttpPost(uploadUrl);
            // 设置请求头
            String token = "Bearer " + isfdTokenService.getToken();
            httpPost.setHeader("Clientid", isfdRequestConfig.getClientId());
            httpPost.setHeader("Authorization", token);

            // 构建multipart/form-data请求体
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(StandardCharsets.UTF_8);

            // 添加文件部分
            builder.addPart("file", new FileBody(file, ContentType.DEFAULT_BINARY));

            // 添加其他表单参数
            formParams.forEach((key, value) ->
                    builder.addTextBody(key, value, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))
            );

            HttpEntity multipart = builder.build();
            httpPost.setEntity(multipart);

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                HttpEntity responseEntity = response.getEntity();
                String responseString = EntityUtils.toString(responseEntity);
                IsfdModelUploadDomain isfdModelUploadDomain = JSON.parseObject(responseString, IsfdModelUploadDomain.class);
                EntityUtils.consume(responseEntity);

                logger.info("Upload response: {}", responseString);
                return isfdModelUploadDomain;
            }
        } catch (IOException | ParseException e) {
            logger.error("Error uploading file", e);
            throw new RuntimeException("File upload failed", e);
        }
    }
}